package cn.virens.app;

import java.lang.management.ManagementFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.virens.app.cmpt.Component;
import cn.virens.app.cmpt.ComponentRegistry;
import cn.virens.app.timer.TimedTaskRegistry;

public abstract class ApplicationLoader implements Component {
	protected static final Logger logger = LoggerFactory.getLogger(ApplicationLoader.class);

	private static final TimedTaskRegistry TASK_REGISTRY = new TimedTaskRegistry();
	private static final ComponentRegistry CMPT_REGISTRY = new ComponentRegistry();

	private static final AppConfig APP_CONFIG = AppConfigImpl.of("config.setting");

	protected static <T extends ApplicationLoader> void load(T application, String[] args) throws Exception {
		logger.debug("The Server starting...");
		logger.debug("Load App...");

		// 启动应用
		application.startComponent(CMPT_REGISTRY, args);
		application.startTimedTask(TASK_REGISTRY, args);
		application.initialize(APP_CONFIG);

		// 组件初始化
		CMPT_REGISTRY.initialize(APP_CONFIG);
		TASK_REGISTRY.initialize(APP_CONFIG);

		// 获取应用运行信息
		String runInf = ManagementFactory.getRuntimeMXBean().getName();
		String[] runInfo = runInf.split("@", 2);

		logger.debug("The Server pid:" + runInfo[0]);
		logger.debug("The Server pkg:" + runInfo[1]);
		logger.debug("The Server started...");
		logger.debug("The Server runing...");
	}

	/** 应用停止 */
	protected static <T extends ApplicationLoader> void unload(T application, String[] args) {
		try {
			logger.debug("The Server stoping...");

			// 组件销毁
			TASK_REGISTRY.destroy();
			CMPT_REGISTRY.destroy();

			logger.debug("Stop App...");

			// 执行应用销毁
			application.stopTimedTask(TASK_REGISTRY);
			application.stopComponent(CMPT_REGISTRY);
			application.destroy();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			logger.debug("The Server stoped.");
		}
	}

	/**
	 * 应用(定时器)启动
	 * 
	 * @param regtimer 定时器注册器
	 * @param args     启动参数
	 */
	protected abstract void startTimedTask(TimedTaskRegistry regtimer, String[] args);

	/**
	 * 应用(定时器)停止
	 * 
	 * @param regtimer 定时器注册器
	 */
	protected abstract void stopTimedTask(TimedTaskRegistry regtimer);

	/**
	 * 应用(组件)启动
	 * 
	 * @param regcmpt 组件注册器
	 * @param args    启动参数
	 */
	protected abstract void startComponent(ComponentRegistry regcmpt, String[] args);

	/**
	 * 应用(组件)停止
	 * 
	 * @param regcmpt 组件注册器
	 */
	protected abstract void stopComponent(ComponentRegistry regcmpt);
}
